import { onUnmounted, ref, watchEffect } from 'vue'
import { defineStore } from 'pinia'
import { setValue, getIndex } from '@/common/utils'
import { HISTORY_SIZE } from '@/common/constant'
import { getSearch } from '@/common/http.api'
import { usePlayerStore } from '@/stores/player'

export const useSearchStore = defineStore(
  'search',
  () => {
    // 获取 播放器 数据和方法
    const playerStore = usePlayerStore()

    // 搜索关联项
    const searchSuggest = ref([])

    // 搜索返回数据
    const searchList = ref({
      songlist: [],
      playlist: [],
    })

    // 搜索关键词历史记录及热门搜索
    const searchHistoryAtHot = ref([
      {
        name: '搜索历史',
        list: ['五月天', '温柔', '七里香', '凉凉', '平凡的路'],
      },
      {
        name: '热门搜索',
        list: [
          '五月天',
          '温柔',
          '周杰伦',
          '七里香',
          '凉凉',
          '平凡的路',
          '奢香夫人',
          '错位时空',
        ],
      },
    ])

    // 显示加载
    const loading = ref(false)
    // 加载更多状态
    const loadStatus = ref('loadmore')
    // 是否更多加载
    const scrollTolower = ref(false)
    // 页数
    const pageNum = ref(1)

    /**
     * 根据关键词查找数据
     * @param keywords 搜索关键词
     * @param pn 页数
     */
    const setSearch = async (keywords, pn = pageNum.value, type = 0) => {
      let list
      // 是否滚动加载更多，是就执行以下
      if (scrollTolower.value)
        setValue({ target: loadStatus, value: 'loading' })
      else setValue({ target: loading, value: true }) // 显示加载

      // 搜索歌曲-0
      if (type === 0) {
        // 添加搜索历史
        searchHistoryAtHot.value[0].list.unshift(keywords)
        // 去重数组
        const uniqueArray = searchHistoryAtHot.value[0].list.reduce(
          (item, current) => {
            if (item.indexOf(current) === -1) item.push(current)
            return item
          },
          []
        )
        // 去重赋值
        searchHistoryAtHot.value[0].list = uniqueArray
        // 添加历史大于最大数就执行
        if (searchHistoryAtHot.value[0].list.length > HISTORY_SIZE)
          searchHistoryAtHot.value[0].list.splice(HISTORY_SIZE, 1)
        // 根据关键词获取歌曲/歌手数据
        list = await getSearch('song', keywords, pn)
      } else {
        // 根据关键词获取歌单数据
        list = await getSearch('playlist', keywords)
      }

      // 1. 创建正则表达式（不区分大小写）
      const regex = new RegExp(`(${keywords})`, 'gi')
      // 2. 拆分文本并处理高亮
      const parts = list.map((song) => {
        const id = song.id ? parseInt(song.id) : song.rid
        const highlight = `<span class="highlight">${keywords}</span>`
        const namePart = song.name.replace(regex, highlight)
        const artistPart =
          type === 0 ? song.artist.replace(regex, highlight) : ''

        return Object.assign({}, song, {
          id: id,
          name: namePart,
          artist: artistPart,
          pic: song.coverImgUrl ? song.coverImgUrl : song.pic,
        })
      })

      // 搜索歌曲-0  把数据放到列表中
      if (type === 0) searchList.value.songlist.push(...parts)
      else searchList.value.playlist.push(...parts)

      // 是否滚动加载更多，是就执行以下
      if (scrollTolower.value) {
        setValue([
          { target: scrollTolower, value: false },
          { target: loadStatus, value: 'loadmore' },
        ])
      } else setValue({ target: loading, value: false }) // 隐藏加载
    }

    /**
     * 滚动加载更多
     * @param {*} keywords 搜索关键词
     */
    const setScrollTolower = (keywords) => {
      if (loadStatus.value === 'loadmore') {
        pageNum.value += 1
        setValue({ target: scrollTolower, value: true })
        setSearch(keywords, pageNum.value)
      }
    }

    const setSearchSuggest = async (keywords) => {
      let list = await getSearch('suggest', keywords)

      setValue({ target: searchSuggest, value: list })
    }

    // 清空搜索数据
    const clearSearchInfo = () => {
      searchList.value.songlist = []
      searchList.value.playlist = []
      setValue([
        { target: searchSuggest, value: [] },
        { target: pageNum, value: 1 },
        { target: loading, value: false },
      ])
    }

    // 清空搜索历史
    const clearHistory = () => {
      searchHistoryAtHot.value[0].list = []
      uni.$u.toast('已清空搜索历史~')
    }

    // 侦听器
    const stopWatch = watchEffect(
      () => {
        // 根据收藏歌曲和队列在列表设置标识
        searchList.value.songlist.forEach((song) => {
          // 获取队列索引
          const curQueueIdx = getIndex(playerStore.playerQueue, song.id)
          // 获取歌曲喜欢索引
          const curSongLikeIdx = getIndex(
            playerStore.playerCollect.songlist,
            song.id
          )
          // 设置播放标识
          song.addQueue = curQueueIdx > -1
          // 设置收藏歌曲标识
          song.like = curSongLikeIdx > -1
        })

        // 根据收藏歌单在列表设置收藏标识
        searchList.value.playlist.forEach((playlist) => {
          // 获取歌单收藏索引
          const curPlaylistIdx = getIndex(
            playerStore.playerCollect.playlist,
            playlist.id
          )
          // 设置收藏标识
          playlist.like = curPlaylistIdx > -1
        })
      },
      { flush: 'post' } // 在组件渲染之后执行副作用函数
    )

    // 停止侦听器
    onUnmounted(() => stopWatch())

    return {
      searchSuggest,
      searchHistoryAtHot,
      searchList,
      scrollTolower,
      loading,
      loadStatus,
      pageNum,
      setSearch,
      setScrollTolower,
      setSearchSuggest,
      clearSearchInfo,
      clearHistory,
    }
  },
  {
    persist: true, // 开启后对 state 的数据读写都将持久化
  }
)
